<html>
<head>
<title>开发笔记.md</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
.s0 { color: #cc7832;}
.s1 { color: #a9b7c6;}
.s2 { color: #a9b7c6;}
.s3 { color: #808080;}
</style>
</head>
<body bgcolor="#2b2b2b">
<table CELLSPACING=0 CELLPADDING=5 COLS=1 WIDTH="100%" BGCOLOR="#606060" >
<tr><td><center>
<font face="Arial, Helvetica" color="#000000">
开发笔记.md</font>
</center></td></tr></table>
<pre><span class="s0"># </span><span class="s2">启动vue项目</span>

<span class="s0">- </span><span class="s2">安装依赖包 进去你所创建的项目 输入命令  </span>
<span class="s3">```$xslt</span>
<span class="s3">npm install</span>
<span class="s3">```</span>
<span class="s0">- </span><span class="s2">启动项目</span>
<span class="s3">```$xslt</span>
<span class="s3">npm run dev</span>
<span class="s3">```</span>

<span class="s0"># </span><span class="s2">实体类设计</span>

<span class="s2">由于使用分布式系统，id由系统产生，在实体类上必须使用@MysqlAutoPK注解</span>
<span class="s3">```$xslt</span>
<span class="s3">@Data</span>
<span class="s3">@Table(name = &quot;hbl_admin_channel&quot;)</span>
<span class="s3">public class HblAdminChannel implements Serializable {</span>

<span class="s3">/**</span>
 <span class="s3">* 分布式id</span>
 <span class="s3">*/</span>
<span class="s3">@MysqlAutoPK</span>
<span class="s3">private Long id;</span>
<span class="s3">/**</span>
 <span class="s3">* 渠道名称</span>
 <span class="s3">*/</span>
<span class="s3">private String name;</span>
<span class="s3">...</span>
<span class="s3">}</span>
<span class="s3">```</span>
<span class="s2">如果不指定亦可以手动插入。</span>


<span class="s0"># </span><span class="s2">插入记录</span>

<span class="s2">插入记录时不要手动指定ID</span>
<span class="s3">```$xslt</span>
<span class="s3">//执行插入操作</span>
<span class="s3">adminChannel.setId(SnowFlakeUtil.getNextId());</span>
<span class="s3">mBaseDao.saveObject(adminChannel);</span>
<span class="s3">return R.ok();</span>
<span class="s3">```</span>

<span class="s0"># </span><span class="s2">Feign调用服务</span>

<span class="s0">##</span><span class="s2">1. 定义Feign客户端接口</span>
<span class="s3">```$xslt</span>
<span class="s3">@FeignClient(name = &quot;zbl-sso&quot;, configuration = FeignRequestInterceptor.class)</span>
<span class="s3">public interface SsoFeignClient {</span>
    <span class="s3">/**</span>
     <span class="s3">* 用户登录</span>
     <span class="s3">*</span>
     <span class="s3">* @param loginEntity</span>
     <span class="s3">* @return</span>
     <span class="s3">*/</span>
    <span class="s3">@PostMapping(&quot;/passport/login&quot;)</span>
    <span class="s3">R login(@RequestBody SysLoginEntity loginEntity);</span>

    <span class="s3">/**</span>
     <span class="s3">* 部门列表</span>
     <span class="s3">*</span>
     <span class="s3">* @return</span>
     <span class="s3">*/</span>
    <span class="s3">@GetMapping(&quot;/auth/dept/list&quot;)</span>
    <span class="s3">R queryDeptList();</span>
<span class="s3">}</span>
<span class="s3">```</span>

<span class="s2">@FeignClient：被改注解修饰的类，可以调用制定微服务。</span>
<span class="s2">注解解释：</span>
<span class="s0">+ </span><span class="s2">name：指定FeignClient的名称，如果项目使用了Ribbon，name属性会作为微服务的名称，用于服务发现</span>
<span class="s0">+ </span><span class="s2">url</span><span class="s1">: </span><span class="s2">url一般用于调试，可以手动指定@FeignClient调用的地址</span>
<span class="s0">+ </span><span class="s2">decode404</span><span class="s1">:</span><span class="s2">当发生http 404错误时，如果该字段位true，会调用decoder进行解码，否则抛出FeignException</span>
<span class="s0">+ </span><span class="s2">configuration</span><span class="s1">: </span><span class="s2">Feign配置类，可以自定义Feign的Encoder、Decoder、LogLevel、Contract</span>
<span class="s0">+ </span><span class="s2">fallback</span><span class="s1">: </span><span class="s2">定义容错的处理类，当调用远程接口失败或超时时，会调用对应接口的容错逻辑，fallback指定的类必须实现@FeignClient标记的接口</span>
<span class="s0">+ </span><span class="s2">fallbackFactory</span><span class="s1">: </span><span class="s2">工厂类，用于生成fallback类示例，通过这个属性我们可以实现每个接口通用的容错逻辑，减少重复的代码</span>
<span class="s0">+ </span><span class="s2">path</span><span class="s1">: </span><span class="s2">定义当前FeignClient的统一前缀</span>

<span class="s2">其中接口中定义的方法必须和对于某一个服务中的控制器方法保持一致（方法名，返回类型，方法签名，请求路径）。</span>

<span class="s0">## </span><span class="s2">2. 使用feign调用方法</span>

<span class="s2">在需要的类中注入已定义的Feign接口。在具体的方法中即可以调用接口中定义的方法成对其他服务的调用。</span>
<span class="s3">```$xslt</span>
<span class="s3">@Service</span>
<span class="s3">@AllArgsConstructor</span>
<span class="s3">public class AdminChannelServiceImpl implements AdminChannelService {</span>
    <span class="s3">public MybatisBaseDaoCRUD mBaseDao;</span>
    <span class="s3">private ModelMetaObjectHandler modelMetaObjectHandler;</span>
    <span class="s3">private SsoFeignClient ssoFeignClient;</span>
<span class="s3">}</span>
<span class="s3">```</span>

<span class="s2">应用场景：通过feign从sso中心调用用户信息。</span>

<span class="s0"># </span><span class="s2">修改git提交用户名</span>
<span class="s2">在终端执行如下命令</span>
<span class="s3">```$xslt</span>
<span class="s3">git config --global user.name &quot;章钧&quot;</span>
<span class="s3">git config --global user.email zhangjun@haoboli.com</span>
<span class="s3">```</span>

<span class="s0"># </span><span class="s2">客户和用户表</span>

<span class="s2">客户信息存在于zbl-erp-web库中crm_bd_customer。  </span>
<span class="s2">用户信息存在于zbl-hbl-dev库中hbl_app_user。</span>

<span class="s0"># </span><span class="s2">多数据源切换</span>
<span class="s2">代码中应用  </span>
<span class="s3">```$xslt</span>
<span class="s3">//切换数据源，查询客户信息</span>
<span class="s3">try {</span>
    <span class="s3">DynamicDataSource.setDataSourceName(&quot;zbl-erp-pro&quot;);</span>
    <span class="s3">List&lt;CrmBdCustomer&gt; dbCrmBdCustomers = mBaseDao.findAll(CrmBdCustomer.class);</span>

    <span class="s3">//根据时间降序排列，去除重复记录</span>
    <span class="s3">dbCrmBdCustomers.stream()</span>
            <span class="s3">.sorted(Comparator.comparing(CrmBdCustomer::getCreateTime).reversed())</span>
            <span class="s3">.filter(distinctByKey(CrmBdCustomer::getName))</span>
            <span class="s3">.collect(Collectors.toList());</span>

    <span class="s3">//查找满足前台传递的客户</span>
    <span class="s3">crmBdCustomers =  Lists.newArrayList();</span>
    <span class="s3">for (CrmBdCustomer c : dbCrmBdCustomers ) {</span>
        <span class="s3">if (Arrays.asList(customerNames).contains(c.getName())) crmBdCustomers.add(c);</span>
    <span class="s3">}</span>
<span class="s3">} finally {</span>
   <span class="s3">DynamicDataSource.clearDataSourceName();</span>
<span class="s3">}</span>
<span class="s3">```</span>

<span class="s0"># </span><span class="s2">调用中台接口</span>

<span class="s2">使用Feign调用中台通用多数据查询接口  </span>
<span class="s0">+ </span><span class="s2">定义service</span>
<span class="s3">```</span>
<span class="s3">@FeignClient(value = &quot;zbl-bsp&quot;)</span>
<span class="s3">public interface ZblBspService {</span>
    <span class="s3">/**</span>
     <span class="s3">* 查询分页数据通用接口，需传入sql</span>
     <span class="s3">*</span>
     <span class="s3">* @param s 加密后的参数</span>
     <span class="s3">* @return</span>
     <span class="s3">*/</span>
    <span class="s3">@GetMapping(value = &quot;/bsp/findData&quot;, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)</span>
    <span class="s3">public String findData(@RequestBody String s);</span>

    <span class="s3">/**</span>
     <span class="s3">* 查询一条数据通用接口</span>
     <span class="s3">*</span>
     <span class="s3">* @param s</span>
     <span class="s3">* @return</span>
     <span class="s3">*/</span>
    <span class="s3">@GetMapping(value = &quot;/bsp/findOne&quot;, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)</span>
    <span class="s3">public String findOne(@RequestBody String s);</span>

    <span class="s3">/**</span>
     <span class="s3">* 查询多条数据通用接口</span>
     <span class="s3">*</span>
     <span class="s3">* @param id</span>
     <span class="s3">* @return</span>
     <span class="s3">*/</span>
<span class="s3">@GetMapping(value = &quot;/bsp/findList&quot;, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)</span>
<span class="s3">public String findList(@RequestBody String s);</span>
<span class="s3">}</span>

<span class="s3">```</span>
<span class="s0">+ </span><span class="s2">实现类中调用</span>
<span class="s3">```$xslt</span>
<span class="s3">/**</span>
 <span class="s3">* 订单获取优惠券信息</span>
 <span class="s3">*</span>
 <span class="s3">* @param orderNo</span>
 <span class="s3">*/</span>
<span class="s3">public BusiContract getCoupon(String orderNo) {</span>
<span class="s3">String queryCouponSql = &quot;select hac.type,hac.couponMoney from hbl_admin_couponVerifyUse hacVU &quot; +</span>
                <span class="s3">&quot; left join hbl_admin_couponUseDetail hacUD on hacUD.couponNO=hacVU.couponNO &quot; +</span>
                <span class="s3">&quot; left join hbl_admin_coupon hac on hac.id=hacUD.hblAdminCouponId where hacVU.orderNO='&quot; + orderNo + &quot;'&quot;;</span>
        <span class="s3">RequestSqlBodyData requestSqlBodyData = new RequestSqlBodyData();</span>
        <span class="s3">requestSqlBodyData.setDbName(&quot;zbl-hbl-pro&quot;);//数据源</span>
        <span class="s3">requestSqlBodyData.setSql(queryCouponSql);//sql语句</span>
        <span class="s3">requestSqlBodyData.setSrcAppName(&quot;zbl-erp-web&quot;);//应用名称</span>
        <span class="s3">requestSqlBodyData.setSrcMethod(getClass().getName() + &quot;.&quot; + Thread.currentThread().getStackTrace()[1].getMethodName() + &quot;()&quot;);//调用方法名</span>
        <span class="s3">String json = JSONArray.toJSONString(requestSqlBodyData);//请求参数json</span>
        <span class="s3">String encrypt = EncryptUtils.encryptENC(json);//enc加密</span>
        <span class="s3">String result = zblBspService.findOne(encrypt);</span>
        <span class="s3">return null;</span>
<span class="s3">}</span>
<span class="s3">```</span>
<span class="s2">使用RequestSqlBodyData包装相关参数。</span>
</pre>
</body>
</html>